<template>
    <ph-button-group :class="cns" items="center" :justify="justify">
        <ph-button :naked="true" :disabled="prevDisabled" icon="caret-left" @click="goPrev" class="ph-pager-btn">{{state.prev}}</ph-button> 
        <template v-if="!simple" >
            <template v-for="p in cps">
                <ph-button :naked="true" v-if="p>0"
                    :active="cpage===p"
                    :key="p"
                    @click="go(p)"
                    >{{p}}</ph-button>
                <div v-else class="ph-pager-empty" :key="'empty'+p"><ph-icon icon="ellipsis-h"/></div>
            </template>
        </template>
        <ph-button :naked="true" :disabled="nextDisabled" icon-right="caret-right" @click="goNext" class="ph-pager-btn">{{state.next}}</ph-button> 
        <template v-if="!state.small&&!simple">
            <ph-select v-if="showPagesize" :value="state.pagesize" @change="onPagesize">
                <ph-option v-for="(ps,k) in psOptions" :key="k" :value="ps.value">{{ps.title}}</ph-option>
            </ph-select>
            <div v-if="showJump" class="ph-pager-jump">
                <span>去 </span>
                <ph-input type="number" min="1" max="pages" :value="pages" @change="onJump"/>
                <span> 页</span>
            </div> 
            <div v-if="showTotal" class="ph-pager-total"> 共{{total}}条 </div> 
        </template>
    </ph-button-group>
</template>
<script lang="ts">
import { defineComponent, computed, ref, toRefs, PropType, reactive } from 'vue'
import {PhButtonGroup,PhButton,PhIcon} from '../base'
import {PhSelect,PhOption,PhInput} from '../form'
import MediaQuery from 'ph-media'
export default defineComponent({
    components:{PhButton,PhIcon,PhInput,PhButtonGroup,PhSelect,PhOption},
    props:{
        "show-total":{type:Boolean,default:false},
        "show-pagesize":{type:Boolean,default:false},
        "show-jump":{type:Boolean,default:false},
        "pagesize-options":{
            type:Array as PropType<Array<number>>,
            default:()=>[10,20,30,50,100]
        },
        theme:{type:String,default:"dark"},
        justify:{type:String,default:"flex-start"},
        prev:{type:String,default:"上一页"},
        next:{type:String,default:"下一页"},
        pagesize:{type:Number,default:10},
        total:{type:Number,default:100},
        page:{type:Number,default:1},
        simple:{type:Boolean,default:false},
        small:Boolean,
        pagercount:{type:Number,default:5}
    },
    watch:{
        page(v){
            this.cpage = Math.min(v,this.pages)
        }
    },
    setup(props,{ emit }) {
        const match375 = ref(false)
        const state = reactive({
            pagesize:props.pagesize,
            pagercount:props.pagercount,
            small:props.small,
            prev:props.prev,
            next:props.next
        })
        MediaQuery.maxWidth("768px",(matches:boolean)=>{
            state.pagercount = matches?3:props.pagercount
            state.small = matches
            state.prev = !props.simple&&matches?"":props.prev
            state.next = !props.simple&&matches?"":props.next
        })
        
        const cns = computed(()=>{
            return {
                'ph-pager':true,
                'ph-pager-black':props.theme==="black",
                'ph-pager-dark':props.theme==="dark",
                'ph-pager-light':props.theme==="light",
                'ph-pager-primary':props.theme==="primary",
                'ph-pager-success':props.theme==="success",
                'ph-pager-danger':props.theme==="danger",
                'ph-pager-warning':props.theme==="warning",
                'ph-pager-transparent':props.theme==="transparent"
            }
        })
        const psOptions = computed(()=>{
            return ((props as Record<string,unknown>).pagesizeOptions as number[]).map((o:number)=>{
                return {
                    value:o,
                    title:o+'条/页'
                }
            })
        })
        const pages = computed(()=>{
            return Math.ceil(props.total / state.pagesize);
        })
        const cpage = ref(Math.min(props.page,pages.value));
        const prevDisabled = computed(()=>cpage.value<=1);
        const nextDisabled = computed(()=>cpage.value>=pages.value);

        const cps = computed(()=>{
            const ps = state.pagercount
            let cps:number[]=[],
                lp:number;
            if(pages.value<=ps){
                for(let i=1;i<=pages.value;i++)
                    cps.push(i)
            }else{
                if(cpage.value>=ps){
                    lp = pages.value-cpage.value
                    cps.push(1)
                    state.small||cps.push(-1)
                    if(lp<=3){
                        for(let i=ps-lp;i>0;i--){
                            if(cpage.value-i>1)
                                cps.push(cpage.value-i)
                        }
                        cps.push(cpage.value)
                        for(let i=1;i<=lp;i++){
                            cps.push(cpage.value+i)
                        }
                    }else{
                        const span = Math.floor(ps/2)
                        for(let i=span;i>0;i--)
                            cps.push(cpage.value-i)
                        // cps.push(cpage.value-2)
                        // cps.push(cpage.value-1)
                        cps.push(cpage.value)
                        // cps.push(cpage.value+1)
                        // cps.push(cpage.value+2)
                        for(let i=1;i<=span;i++)
                            cps.push(cpage.value+i)

                        state.small||cps.push(-1)
                        cps.push(pages.value)
                    }
                }else{
                    for(let i=1;i<=ps;i++){
                        cps.push(i)
                    }
                    cps.push(-1)
                    cps.push(pages.value)
                }
            }
            
            return cps
        })

        const goPage = (page:number,ps?:number)=>{
            emit("page",{page,pagesize:ps||state.pagesize})
        }
        const onJump = (value:number)=>{
            if(!value)return
            if(value<1||value>pages.value)return
            goPage(value)
        }
        const onPagesize = (value:number)=>{
            if(!value)return
            //避免抖动
            setTimeout(()=>{
                //判断当前page是否溢出
                const pages = Math.ceil(props.total / value)
                if(props.page>pages)
                    goPage(pages,value)
                state.pagesize = value
            },200)
        }
        const goNext = ()=>{
            goPage(props.page+1)
        }
        const goPrev = ()=>{
            goPage(props.page-1)
        }
        const go = (p:number)=>{
            if(props.page===p)return
            goPage(p)
        }

        return {
            cns,
            cps,
            prevDisabled,
            nextDisabled,
            pages,
            cpage,
            state,
            psOptions,

            onPagesize,
            onJump,
            goPage,
            goNext,
            goPrev,
            go,

        }
    },
})
</script>
<style lang="scss">
    @import '../../assets/scss/predef.scss';
    .ph-pager{
        color: var(--ph-c);
        flex-wrap: nowrap!important;
        overflow: visible;
        --ph-pager-color: var(--ph-c);
        --ph-pager-color-dark: var(--ph-c-d1);
        --ph-pager-color-active: var(--ph-c-light);
        --ph-pager-bg-disabled:var(--ph-bg-disabled);
        --ph-pager-bg-hover: var(--ph-light);
        --ph-pager-bg-active: var(--ph-theme);
        --ph-pager-bg: transparent;
        --ph-pager-bd: var(--ph-bd-light);
        &-black{
            --ph-pager-bd: var(--ph-dark-d1);
            --ph-pager-color: var(--ph-c-l2);
            --ph-pager-color-dark: var(--ph-c-light);
            --ph-pager-bg: var(--ph-dark);
            --ph-pager-bg-hover: var(--ph-dark-d1);
            --ph-pager-bg-active: var(--ph-dark-d1);
            --ph-pager-bg-disabled:var(--ph-dark);
        }
        &-dark{
            --ph-pager-bg-active: var(--ph-dark);
            --ph-pager-bg: var(--ph-light-l1);
        }
        &-light{
            --ph-pager-bg-active: var(--ph-theme);
            --ph-pager-bg: var(--ph-light-l1);
        }
        &-primary{
            --ph-pager-bg-active:var(--ph-blue);
            --ph-pager-bd:var(--ph-blue-bga3);
        }
        &-success{
            --ph-pager-bg-active:var(--ph-green);
            --ph-pager-bd:var(--ph-green-bga3);
        }
        &-danger{
            --ph-pager-bg-active:var(--ph-red);
            --ph-pager-bd:var(--ph-red-bga3);
        }
        &-warning{
            --ph-pager-bg-active:var(--ph-orange);
            --ph-pager-bd:var(--ph-orange-bga3);
        }
        &-transparent{
            --ph-pager-bd: transparent;
            --ph-pager-bg-disabled:transparent;
        }
        & > .ph-action,
        &-empty{
            min-width: calc(var(--phx) * 3);
            padding: var(--ph-8) var(--phx);
            flex: 0 0 auto;
            line-height: 1;
            color: var(--ph-pager-color);
            background-color: var(--ph-pager-bg);
            border-color: var(--ph-pager-bd);
            & + .ph-action{
                margin-left: -1px!important;
            }
        }
        & > .ph-action{
            &:hover{
                color: var(--ph-pager-color-dark);
                background-color: var(--ph-pager-bg-hover);
            }
            &-active,
            &-active:hover{
                color: var(--ph-pager-color-active);
                @include bg(var(--ph-pager-bg-active));
            }
            &:disabled,
            &:disabled:hover{
                color: var(--ph-pager-color)!important;
                background-color: var(--ph-pager-bg-disabled)!important;
                border-color: var(--ph-pager-bd)!important;
                opacity: .7!important;
            }
        }
        .ph-pager-btn{
            span{
                margin-left:0!important;
            }
        }
        &-empty{
            border-width: 1px;
            border-style: solid;
            margin-left: -1px;
            text-align: center;
            .ph-icon{
                line-height: inherit;
            }
        }
        
        &-total,
        &-jump{
            white-space: nowrap;
            margin-left: var(--ph-5);
            font-size: var(--ph-fs-small);
        }
        &-jump{
            .ph-input{
                width:calc(var(--phx) * 4.27)
            }
        }
        .ph-input{
            padding: var(--ph-10) 0 var(--ph-10) var(--ph-10);
            flex: 0 0 auto;
            line-height: 1;
            border-radius: 0;
            font-size: var(--ph-fs-small);
            height: calc(var(--phx) * 2.2857);
            display: inline-block;
        }
        &:not(.ph-pager-transparent):not(.ph-pager-black) .ph-input{
            border-color: var(--ph-pager-bd);
        }
        .ph-select-wrap{
            width: calc(var(--phx) * 6.07);
            margin-left: var(--ph-5);
            flex: 0 0 auto;
            font-size: var(--ph-fs-small);
        }
    }
    @media (max-width:768px){
        .ph-pager{
            justify-content:center!important;
            & > .ph-action,
            &-empty{
                padding: var(--ph-8) var(--ph-10);
            }
        }
    }
</style>
